package org.wu.framework.lazy.orm.database.lambda.dynamic.function;


import org.wu.framework.lazy.orm.core.config.enums.LazyDataSourceType;
import org.wu.framework.lazy.orm.core.persistence.conf.LazyDynamicEndpoint;
import org.wu.framework.lazy.orm.core.toolkit.DynamicLazyDataSourceTypeHolder;
import org.wu.framework.lazy.orm.database.lambda.dynamic.toolkit.DynamicLazyDSContextHolder;

/**
 * 切换数据源然后摸摸执行方法
 *
 * @see DynamicLazyDSContextHolder
 */
public final class DynamicDatasourceSupport {

    /**
     * 当使用的数据源类型与当前服务使用的数据源一致时 切换数据源 并返回结果
     *
     * @param name               数据源名称
     * @param schema             数据库
     * @param datasourceConsumer 切换数据源后执行的方法
     */
    public static <T> T doSameSilently(String name, String schema, DynamicDatasourceConsumerQuery<T> datasourceConsumer) {

        // 获取上一个数据源
        LazyDynamicEndpoint dynamicEndpoint = DynamicLazyDSContextHolder.peek();
        LazyDataSourceType lazyDataSourceType = DynamicLazyDataSourceTypeHolder.peek();
        try {
            // 切换
            DynamicLazyDSContextHolder.switchDatasourceAndSchema(name, schema);
            return datasourceConsumer.accept();
        } catch (Throwable throwable) {
            throw new RuntimeException(throwable);
        } finally {
            DynamicLazyDSContextHolder.clear();
            if (dynamicEndpoint != null) {
                DynamicLazyDSContextHolder.push(dynamicEndpoint);
            }
            if (lazyDataSourceType != null) {
                DynamicLazyDataSourceTypeHolder.push(lazyDataSourceType);
            }
        }

    }

    /**
     * 当使用的数据源类型与当前服务使用的数据源一致时 切换数据源
     * @param name 数据源名称
     * @param schema 数据库
     * @param datasourceConsumer 切换数据源后执行的方法
     *
     */
    public static void doSameSilently(String name, String schema, DynamicDatasourceConsumer datasourceConsumer) {

        // 获取上一个数据源
        LazyDynamicEndpoint dynamicEndpoint = DynamicLazyDSContextHolder.peek();
        LazyDataSourceType lazyDataSourceType = DynamicLazyDataSourceTypeHolder.peek();
        try {
            // 切换
            DynamicLazyDSContextHolder.switchDatasourceAndSchema(name, schema);
            datasourceConsumer.accept();
        } catch (Throwable throwable) {
            throw new RuntimeException(throwable);
        } finally {
            DynamicLazyDSContextHolder.clear();
            if (dynamicEndpoint != null) {
                DynamicLazyDSContextHolder.push(dynamicEndpoint);
            }
            if (lazyDataSourceType != null) {
                DynamicLazyDataSourceTypeHolder.push(lazyDataSourceType);
            }
        }

    }

    /**
     * 当使用的数据源类型与当前服务使用的数据源不一致时 切换数据源 并返回结果
     *
     * @param dataSourceType     数据源类型
     * @param name               数据源名称
     * @param schema             数据库
     * @param datasourceConsumer 切换数据源后执行的方法
     */
    public static <T> T doOtherSilently(LazyDataSourceType dataSourceType, String name, String schema, DynamicDatasourceConsumerQuery<T> datasourceConsumer) {

        // 获取上一个数据源
        LazyDynamicEndpoint dynamicEndpoint = DynamicLazyDSContextHolder.peek();
        // 切换使用的数据源类型
        LazyDataSourceType lazyDataSourceType = DynamicLazyDataSourceTypeHolder.peek();
        try {
            // 切换
            DynamicLazyDSContextHolder.switchDatasourceAndSchema(name, schema);
            DynamicLazyDataSourceTypeHolder.push(dataSourceType);
            return datasourceConsumer.accept();
        } catch (Throwable throwable) {
            throw new RuntimeException(throwable);
        } finally {
            DynamicLazyDSContextHolder.clear();
            DynamicLazyDataSourceTypeHolder.clear();
            if (dynamicEndpoint != null) {
                DynamicLazyDSContextHolder.push(dynamicEndpoint);
            }
            if (lazyDataSourceType != null) {
                DynamicLazyDataSourceTypeHolder.push(lazyDataSourceType);
            }
        }

    }
    /**
     * 当使用的数据源类型与当前服务使用的数据源不一致时 切换数据源
     *
     * @param dataSourceType     数据源类型
     * @param name               数据源名称
     * @param schema             数据库
     * @param datasourceConsumer 切换数据源后执行的方法
     */
    public static void doOtherSilently(LazyDataSourceType dataSourceType, String name, String schema, DynamicDatasourceConsumer datasourceConsumer) {

        // 获取上一个数据源
        LazyDynamicEndpoint dynamicEndpoint = DynamicLazyDSContextHolder.peek();
        // 切换使用的数据源类型
        LazyDataSourceType lazyDataSourceType = DynamicLazyDataSourceTypeHolder.peek();
        try {
            // 切换
            DynamicLazyDSContextHolder.switchDatasourceAndSchema(name, schema);
            DynamicLazyDataSourceTypeHolder.push(dataSourceType);
            datasourceConsumer.accept();
        } catch (Throwable throwable) {
            throw new RuntimeException(throwable);
        } finally {
            DynamicLazyDSContextHolder.clear();
            DynamicLazyDataSourceTypeHolder.clear();
            if (dynamicEndpoint != null) {
                DynamicLazyDSContextHolder.push(dynamicEndpoint);
            }
            if (lazyDataSourceType != null) {
                DynamicLazyDataSourceTypeHolder.push(lazyDataSourceType);
            }
        }

    }
}
